我们经常看到的"!!obj"
相信大家在偶尔看到一些库的源码时,总是能看到这样一句语法a === true && !!obj;
, 是的,这里面用了!!obj 这样一个运算符。我们不禁好奇,这样做的结果不就是等于什么都没做吗?最近在看老姚的《underscore源码解析》恰好也有这么一段,作者做了解释,我自己也求证了一下。
_.isObject()方法
源码如下
1 | _.isObject = function(obj){ |
可以看到,如果 typeof
的值为‘function’则直接返回true
, 否则返回是否是object。 但是其实多做了一步,作者解释是为了避免null的值。
后面的!!obj是拿到obj的布尔值。目的是为了排除null。
!!obj 返回了什么
我们申明简单的对象,以及空对象,可以直接看到这段表达式返回了什么
1 | // 正常对象 |
对于正常的非空对象,返回true
,对于null则返回false
。But wait!!, 这有啥用?难道我们平时不是直接 if(type === 'object' && obj) {}
就可以了吗?
!!obj 为什么要这么写
其实作者有举一个例子说明:
1 | if (20 && 30) { |
此处 if语句的返回结果显然是true, 但是 20 && 30
的返回结果其实是30(因为会读取最后一个的值,故而 20 && 30 && 10
会返回10。同理,20 || 30 || 10
会返回 20), 之所以返回了true是因为if
语句进行的类型转换。
对于不在if语句以内的表达式,如果我们也需要返回bool值呢?是的这时候!!obj
就派上了用场,他返回的是bool值,而且恰好和我们需求中的是否为null对应了起来。
因此 !!
并没有什么特殊的功能,他就是做了两次非运算,然后返回了运算的结果, true
或者 false
。